package content

import (
	"context"
	"gf_blog_admin/internal/dao"
	"gf_blog_admin/internal/model"
	"gf_blog_admin/internal/service"
	"gf_blog_admin/utility/utils"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
)

type sArticleCate struct{}

func init() {
	service.RegisterArticleCate(NewArticleCate())
}

func NewArticleCate() *sArticleCate {
	return &sArticleCate{}
}

func (s *sArticleCate) List(ctx context.Context, in *model.ArticleCateListInput) (out []*model.ArticleCateItem, err error) {
	var (
		cls = dao.BlArticleCategory.Columns()
		m   = dao.BlArticleCategory.Ctx(ctx)
	)

	if in.ParentId != "" {
		m = m.Where(cls.ParentId, utils.StrToInt(in.ParentId))
	}

	out = make([]*model.ArticleCateItem, 0)
	err = m.OrderDesc(cls.CateSort).OrderDesc(cls.Id).
		Fields(cls.Id, cls.ParentId, cls.CateName, cls.CateSlug, cls.CateSort, cls.CateStatus).
		Scan(&out)
	return
}

func (s *sArticleCate) Store(ctx context.Context, in *model.ArticleCateFormInput) (err error) {
	cls := dao.BlArticleCategory.Columns()

	if err = utils.IsUnique(ctx, &dao.BlArticleCategory, map[string]string{
		cls.CateName: in.CateName,
	}, "分类名已存在"); err != nil {
		return err
	}

	err = dao.BlArticleCategory.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = dao.BlArticleCategory.Ctx(ctx).Data(in).Insert()
		return err
	})
	return
}

func (s *sArticleCate) Update(ctx context.Context, id uint64, in *model.ArticleCateFormInput) (err error) {
	var (
		check bool
		cls   = dao.BlArticleCategory.Columns()
		m     = dao.BlArticleCategory.Ctx(ctx)
	)

	if err = utils.IsUnique(ctx, &dao.BlArticleCategory, map[string]interface{}{
		cls.Id + " !=": id,
		cls.CateName:   in.CateName,
	}, "分类名已存在"); err != nil {
		return err
	}

	if check, err = m.Where(cls.Id, id).Exist(); err != nil {
		return err
	} else if !check {
		return gerror.New("分类不存在")
	}

	return dao.BlArticleCategory.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = m.Where(cls.Id, id).Data(in).Update()
		return nil
	})
}

func (s *sArticleCate) Destroy(ctx context.Context, ids []uint64) (err error) {
	var (
		check bool
		cls   = dao.BlArticleCategory.Columns()
		m     = dao.BlArticleCategory.Ctx(ctx)
	)

	ids = utils.UniqueIds(ids)
	if check, err = m.WhereIn(cls.Id, ids).Exist(); err != nil {
		return err
	} else if !check {
		return gerror.New("操作失败")
	}

	if check, err = m.WhereIn(cls.ParentId, ids).Exist(); err != nil {
		return err
	} else if check {
		return gerror.New("分类下存在子类不能删除！")
	}

	check, err = dao.BlArticle.Ctx(ctx).WhereIn(dao.BlArticle.Columns().CategoryId, ids).Exist()
	if err != nil {
		return err
	} else if check {
		return gerror.New("分类下存在关联文章不能删除！")
	}

	err = dao.BlArticleCategory.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = m.WhereIn(cls.Id, ids).Delete()
		return err
	})
	return
}
